package cn.sylinx.hbatis.ext.common.repository;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import cn.sylinx.hbatis.db.common.Callable;
import cn.sylinx.hbatis.db.common.FS;
import cn.sylinx.hbatis.db.common.ITransaction;
import cn.sylinx.hbatis.db.common.Page;
import cn.sylinx.hbatis.db.common.Record;
import cn.sylinx.hbatis.db.dialect.Dialect;
import cn.sylinx.hbatis.db.mapper.ModelBuilder;
import cn.sylinx.hbatis.db.mapper.QueryMapper;
import cn.sylinx.hbatis.ext.common.BaseConst;
import cn.sylinx.hbatis.ext.common.spi.HbatisServiceManager;
import cn.sylinx.hbatis.ext.model.BaseModel;
import cn.sylinx.hbatis.ext.model.GenericModel;
import cn.sylinx.hbatis.ext.res.StatementHandler;
import cn.sylinx.hbatis.kit.Pair;
import cn.sylinx.hbatis.kit.Ret;
import cn.sylinx.hbatis.kit.Tuple;
import cn.sylinx.hbatis.log.GLog;
import cn.sylinx.hbatis.plugin.statement.StatementHandlerManager;

public class CommonDaoServiceImpl implements CommonDaoService {

	private CommonRepository commonRepository;

	public CommonDaoServiceImpl() {

	}

	public CommonDaoServiceImpl(CommonRepository commonRepository) {
		this.commonRepository = commonRepository;
	}

	@Override
	public String getDatasourceName() {
		return commonRepository.getDatabase();
	}

	@Override
	public Dialect getDialect() {
		return commonRepository.getDialect();
	}

	@Override
	public <T> FS<T> createFS(Class<T> clazz) {
		return getDialect().getFluentSqlCreator().create(clazz);
	}

	@Override
	public boolean transaction(ITransaction transactions) {
		return commonRepository.transaction(transactions);
	}

	@Override
	public Ret transactionWithReturn(ITransaction transactions) {
		return commonRepository.transactionWithReturn(transactions);
	}

	@Override
	public <T> T call(Callable<T> callable) {
		return commonRepository.call(callable);
	}

	@Override
	public <T> List<T> query(String sql, QueryMapper<T> mapper, Object... params) {
		return HbatisServiceManager.getHbatisService().use(commonRepository.getDatabase()).query(sql, mapper, params);
	}

	/**
	 * 获取StatementHandler
	 * 
	 * @return
	 */
	protected StatementHandler getStatementHandler() {
		return StatementHandlerManager.get().getStatementHandler(getDatasourceName());
	}

	protected String handlerStatement(String nativeSql) {
		StatementHandler hander = getStatementHandler();
		if (hander == null) {
			return nativeSql;
		}

		String changeSql = hander.handle(nativeSql);
		GLog.debug("nativeSql : {} ", nativeSql);
		GLog.debug("changeSql : {} ", changeSql);
		return changeSql;
	}

	@Override
	public List<Record> queryRecordsWithSql(String nativeSql, Object... params) {
		String changeSql = handlerStatement(nativeSql);
		GLog.debug("params : {} ", params);
		return commonRepository.queryRecords(changeSql, params);
	}

	@Override
	public Record queryRecordWithSql(String nativeSql, Object... params) {
		String changeSql = handlerStatement(nativeSql);
		GLog.debug("params : {} ", params);

		return commonRepository.queryRecord(changeSql, params);
	}

	@Override
	public int updateWithSql(String nativeSql, Object... params) {
		String changeSql = handlerStatement(nativeSql);
		GLog.debug("params : {} ", params);

		return commonRepository.update(changeSql, params);
	}

	@Override
	public boolean executeLargeUpdate(final List<String> nativeExeSqlList) {
		return commonRepository.executeLargeUpdate(nativeExeSqlList);
	}

	@Override
	public boolean existTable(String schema, String table) {
		return commonRepository.existTable(schema, table);
	}

	@Override
	public boolean existTableColumn(String schema, String table, String column) {
		return commonRepository.existTableColumn(schema, table, column);
	}

	@Override
	public <T> List<T> query(Class<T> clz) {

		String sql = getDialect().getSqlBuilder().buildSimpleQuery(clz);

		StatementHandler sh = getStatementHandler();
		if (sh != null) {
			sql = sh.handle(sql);
		}

		QueryMapper<T> mapper = ModelBuilder.buildQueryMapper(clz);
		return HbatisServiceManager.getHbatisService().use(commonRepository.getDatabase()).query(sql, mapper);
	}

	@Override
	public <T> int update(T t) {
		return updateObject(t);
	}

	@Override
	public <T> int updateObject(T t) {

		if (t instanceof BaseModel) {
			// 设置修改时间戳
			((BaseModel) t).setGmtModify(new Date());
		}

		Tuple tp = getDialect().getSqlBuilder().buildUpdateSQL(t);

		String sql = tp.getObject(0, String.class);
		StatementHandler sh = getStatementHandler();
		if (sh != null) {
			sql = sh.handle(sql);
		}
		Object[] params = tp.getObject(1, Object[].class);

		return HbatisServiceManager.getHbatisService().use(commonRepository.getDatabase()).update(sql, params);
	}

	@Override
	public <T> T get(Object id, Class<T> clz) {

		return get(id, clz, false);
	}

	@Override
	public <T> T get(Object id, Class<T> clz, boolean cached) {
		return get(id, clz, null, cached);
	}

	@Override
	public <T> T get(Object id, Class<T> clz, String[] fields) {
		return get(id, clz, fields, false);
	}

	@Override
	public <T> T get(Object id, Class<T> clz, String[] fields, boolean cached) {
		List<T> list = getObjectByField(Arrays.asList(Pair.apply("id", id)), clz, fields, cached);
		return list != null && !list.isEmpty() ? list.get(0) : null;
	}

	@Override
	public <T> T getObject(Object pk, Class<T> clz) {
		return getObjectByField(Pair.apply("id", pk), clz);
	}

	@Override
	public <T> T getByNumber(String number, Class<T> clz) {
		return getByField(Pair.apply("number", number), clz);
	}

	@Override
	public <T> T getObjectByNumber(String number, Class<T> clz) {
		List<T> list = getObjectByField(Arrays.asList(Pair.apply("number", number)), clz);
		return list != null && !list.isEmpty() ? list.get(0) : null;
	}

	@Override
	public <T> T getByField(Pair kv, Class<T> clz) {

		List<T> fs = getByField(Arrays.asList(kv), clz);
		return fs != null && !fs.isEmpty() ? fs.get(0) : null;
	}

	@Override
	public <T> T getObjectByField(Pair kv, Class<T> clz) {
		List<T> list = getObjectByField(Arrays.asList(kv), clz);
		return list != null && !list.isEmpty() ? list.get(0) : null;
	}

	@Override
	public <T> List<T> getByField(List<Pair> kvList, Class<T> clz) {
		return getObjectByField(kvList, clz);
	}

	@Override
	public <T> List<T> getObjectByField(List<Pair> kvList, Class<T> clz) {
		return getObjectByField(kvList, clz, false);
	}

	@Override
	public <T> List<T> getObjectByField(List<Pair> kvList, Class<T> clz, boolean cached) {

		return getObjectByField(kvList, clz, null, cached);
	}

	@Override
	public <T> List<T> getObjectByField(List<Pair> kvList, Class<T> clz, String[] fields) {
		return getObjectByField(kvList, clz, fields, false);
	}

	@Override
	public <T> Record getRecordByField(Pair pair, Class<T> clz) {
		return getRecordByField(Arrays.asList(pair), clz);
	}

	@Override
	public <T> Record getRecordByField(List<Pair> kvList, Class<T> clz) {
		List<Record> records = getRecordsByField(kvList, clz);
		return records != null && !records.isEmpty() ? records.get(0) : null;
	}

	@Override
	public <T> List<Record> getRecordsByField(List<Pair> kvList, Class<T> clz) {
		return getRecordsByField(kvList, clz, null);
	}

	@Override
	public <T> List<Record> getRecordsByField(List<Pair> kvList, Class<T> clz, String[] fields) {
		return getRecordsByField(kvList, clz, fields, false);
	}

	@Override
	public <T> List<T> getObjectByField(List<Pair> kvList, Class<T> clz, String[] fields, boolean cached) {

		Tuple kv = getDialect().getSqlBuilder().buildQueryByFieldSQL(kvList, clz, fields);
		String sql = kv.getObject(0);
		Object[] params = kv.getObject(1);
		StatementHandler sh = getStatementHandler();
		GLog.debug("origin sql: {}, params: {}", sql, params);

		if (sh != null) {
			sql = sh.handle(sql);
			GLog.debug("changed sql: {} ", sql);
		}

		if (cached) {
			return querySqlListWithCache(sql, clz, params);
		}

		return querySqlList(sql, clz, params);
	}

	@Override
	public <T> List<Record> getRecordsByField(List<Pair> kvList, Class<T> clz, String[] fields, boolean cached) {

		Tuple kv = getDialect().getSqlBuilder().buildQueryByFieldSQL(kvList, clz, fields);
		String sql = kv.getObject(0);
		Object[] params = kv.getObject(1);
		StatementHandler sh = getStatementHandler();
		GLog.debug("origin sql: {}, params: {}", sql, params);

		if (sh != null) {
			sql = sh.handle(sql);
			GLog.debug("changed sql: {} ", sql);
		}

		if (cached) {
			return querySqlRecordsWithCache(sql, params);
		}

		return queryRecordsWithSql(sql, params);
	}

	@Override
	public <T> int delete(T t) {

		Tuple tp = getDialect().getSqlBuilder().buildDeleteSQL(t);

		String sql = tp.getObject(0, String.class);
		StatementHandler sh = getStatementHandler();
		if (sh != null) {
			sql = sh.handle(sql);
		}

		Object[] params = tp.getObject(1, Object[].class);

		return HbatisServiceManager.getHbatisService().use(commonRepository.getDatabase()).update(sql, params);
	}

	@Override
	public <T> int deleteByPk(Object id, Class<T> clz) {
		return deleteObjectByPk(id, clz);
	}

	@Override
	public <T> int delete(List<Pair> kvList, Class<T> clz) {
		return deleteObject(kvList, clz);
	}

	@Override
	public <T> int deleteObjectByPk(Object pk, Class<T> clz) {
		return deleteObject(Arrays.asList(Pair.apply("id", pk)), clz);
	}

	@Override
	public <T> int deleteObject(List<Pair> kvList, Class<T> clz) {

		Tuple kv = getDialect().getSqlBuilder().buildDeleteByFieldSQL(kvList, clz);
		String sql = kv.getObject(0);
		Object[] params = kv.getObject(1);

		StatementHandler sh = getStatementHandler();
		if (sh != null) {
			sql = sh.handle(sql);
		}

		return HbatisServiceManager.getHbatisService().use(commonRepository.getDatabase()).update(sql, params);
	}
	
	@Override
	public <T> Ret addWithRet(T t) {
		return commonRepository.save(t);
	}

	@Override
	public <T extends GenericModel> T add(T t) {

		if (t instanceof BaseModel) {
			BaseModel t1 = (BaseModel) t;
			// 设置创建时间
			if (t1.getGmtCreate() == null) {
				t1.setGmtCreate(new Date());
			}
			// 设置修改时间
			if (t1.getGmtModify() == null) {
				t1.setGmtModify(new Date());
			}
		}

		Tuple tp = getDialect().getSqlBuilder().buildInsertSQL(t);

		String sql = tp.getObject(0, String.class);
		StatementHandler sh = getStatementHandler();
		if (sh != null) {
			sql = sh.handle(sql);
		}

		Object[] params = tp.getObject(1, Object[].class);

		Serializable pk = HbatisServiceManager.getHbatisService().use(commonRepository.getDatabase()).save(sql, params);
		GLog.info("save with pk:{}", pk);

		if (pk != null) {
			if (t.getId() == null) {
				t.setId(pk);
			}
		}

		return t;
	}

	@Override
	public <T> Serializable addObject(T t) {

		if (t instanceof BaseModel) {
			BaseModel t1 = (BaseModel) t;
			// 设置创建时间
			if (t1.getGmtCreate() == null) {
				t1.setGmtCreate(new Date());
			}
			// 设置修改时间
			if (t1.getGmtModify() == null) {
				t1.setGmtModify(new Date());
			}
		}

		return commonRepository.saveObject(t);
	}

	@Override
	public <T> List<Object> batchAddObject(List<T> objectList) {

		List<Object> pkList = new ArrayList<>();
		boolean ok = transaction(() -> {
			for (T t : objectList) {
				Object pk = addObject(t);
				if (pk == null) {
					return Ret.error();
				}
				pkList.add(pk);
			}
			return Ret.success();
		});

		return ok ? pkList : Collections.emptyList();
	}

	@Override
	public <T> boolean justBatchAddObject(List<T> objectList) {

		return transaction(() -> {
			for (T t : objectList) {
				boolean isok = justAddObject(t);
				if (!isok) {
					return Ret.error();
				}
			}
			return Ret.success();
		});
	}

	@Override
	public Object insert(String insertSql, Object... params) {
		return commonRepository.insert(insertSql, params);
	}

	@Override
	public <T> boolean justAddObject(T t) {

		if (t instanceof BaseModel) {
			BaseModel t1 = (BaseModel) t;
			// 设置创建时间
			if (t1.getGmtCreate() == null) {
				t1.setGmtCreate(new Date());
			}
			// 设置修改时间
			if (t1.getGmtModify() == null) {
				t1.setGmtModify(new Date());
			}
		}

		return commonRepository.saveObjectNoPk(t);
	}

	@Override
	public <T> boolean justAdd(T t) {
		return justAddObject(t);
	}

	@Override
	public <T> Page<T> queryPage(String sql, int pageNumber, int pageSize, Class<T> clz, Object... params) {

		String preSql = sql;
		Tuple t = getDialect().getSqlBuilder().buildPaginatorSql(preSql, pageNumber, pageSize);

		StatementHandler sh = getStatementHandler();
		String sqlCount = t.getObject(0);
		if (sh != null) {
			sqlCount = sh.handle(sqlCount);
		}

		Record r = commonRepository.queryRecord(sqlCount, params);
		int totalRow = r == null ? 0 : Integer.valueOf(r.get("totalCount").toString());
		if (totalRow == 0) {
			// 空
			Page<T> emptyPage = new Page<T>();
			emptyPage.setPageSize(pageSize);
			return emptyPage;
		}

		int totalPage = (int) (totalRow / pageSize);
		if (totalRow % pageSize != 0) {
			totalPage++;
		}

		String sqlLimit = t.getObject(1);
		Object[] pms = t.getObject(2);

		if (sh != null) {
			sqlLimit = sh.handle(sqlLimit);
		}

		int paramSize = params == null ? 0 : params.length;
		int pageParamSize = pms == null ? 0 : pms.length;
		int finalParamSize = paramSize + pageParamSize;
		Object[] finalParams = new Object[finalParamSize];

		// 查询参数
		if (paramSize > 0) {
			for (int i = 0; i < paramSize; ++i) {
				finalParams[i] = params[i];
			}
		}

		// 分页参数
		if (pageParamSize > 0) {
			for (int i = 0; i < pageParamSize; ++i) {
				finalParams[i + paramSize] = pms[i];
			}
		}

		List<T> dataList = commonRepository.queryList(sqlLimit, clz, finalParams);
		Page<T> page = new Page<T>(dataList, pageNumber, pageSize, totalPage, totalRow);
		return page;
	}

	@Override
	public <T> Page<T> queryPage(Class<T> clz, int pageNumber, int pageSize) {

		String sql = getDialect().getSqlBuilder().buildSimpleQuery(clz);
		return queryPage(sql, pageNumber, pageSize, clz);
	}

	@Override
	public <T> Page<T> queryPage(Class<T> clz, int pageNumber) {
		return queryPage(clz, pageNumber, BaseConst.DEFAULT_PAGE_SIZE_16);
	}

	@Override
	public <T> Page<Record> queryPageRecords(String sql, int pageNumber, int pageSize, Object... params) {

		String preSql = sql;
		Tuple t = getDialect().getSqlBuilder().buildPaginatorSql(preSql, pageNumber, pageSize);

		StatementHandler sh = getStatementHandler();
		String sqlCount = t.getObject(0);
		if (sh != null) {
			sqlCount = sh.handle(sqlCount);
		}

		Record r = commonRepository.queryRecord(sqlCount, params);
		int totalRow = r == null ? 0 : Integer.valueOf(r.get("totalCount").toString());
		if (totalRow == 0) {
			// 空
			Page<Record> emptyPage = new Page<Record>();
			emptyPage.setPageSize(pageSize);
			return emptyPage;
		}

		int totalPage = (int) (totalRow / pageSize);
		if (totalRow % pageSize != 0) {
			totalPage++;
		}

		String sqlLimit = t.getObject(1);
		Object[] pms = t.getObject(2);

		if (sh != null) {
			sqlLimit = sh.handle(sqlLimit);
		}

		int paramSize = params == null ? 0 : params.length;
		int pageParamSize = pms == null ? 0 : pms.length;
		int finalParamSize = paramSize + pageParamSize;
		Object[] finalParams = new Object[finalParamSize];

		// 查询参数
		if (paramSize > 0) {
			for (int i = 0; i < paramSize; ++i) {
				finalParams[i] = params[i];
			}
		}

		// 分页参数
		if (pageParamSize > 0) {
			for (int i = 0; i < pageParamSize; ++i) {
				finalParams[i + paramSize] = pms[i];
			}
		}

		List<Record> dataList = commonRepository.queryRecords(sqlLimit, finalParams);
		Page<Record> page = new Page<Record>(dataList, pageNumber, pageSize, totalPage, totalRow);
		return page;
	}

	@Override
	public <T> Page<Record> queryPageRecords(Class<T> clz, int pageNumber, int pageSize) {

		String preSql = getDialect().getSqlBuilder().buildSimpleQuery(clz);
		return this.queryPageRecords(preSql, pageNumber, pageSize);
	}

	@Override
	public <T> Page<Record> queryPageRecords(Class<T> clz, int pageNumber) {
		return queryPageRecords(clz, pageNumber, BaseConst.DEFAULT_PAGE_SIZE_16);
	}

	@Override
	public <T> List<T> queryWithCache(Class<T> clz) {

		String sql = getDialect().getSqlBuilder().buildSimpleQuery(clz);
		StatementHandler sh = getStatementHandler();
		if (sh != null) {
			sql = sh.handle(sql);
		}

		return querySqlListWithCache(sql, clz);
	}

	@Override
	public <T> List<T> querySqlList(String sql, Class<T> clz, Object... params) {
		return commonRepository.queryList(sql, clz, params);
	}

	@Override
	public <T> T querySqlFirst(String sql, Class<T> clz, Object... params) {
		List<T> dataList = querySqlList(sql, clz, params);
		if(dataList != null && !dataList.isEmpty()) {
			return dataList.get(0);
		}
		return null;
	}

	@Override
	public <T> List<T> querySqlListWithCache(String nativeSql, Class<T> clz, Object... params) {
		return commonRepository.queryListWithCache(nativeSql, clz, params);
	}

	@Override
	public <T> T querySqlFirstWithCache(String nativeSql, Class<T> clz, Object... params) {
		return commonRepository.queryFirstWithCache(nativeSql, clz, params);
	}

	@Override
	public List<Record> querySqlRecordsWithCache(String sql, Object... params) {
		return commonRepository.queryRecordsWithCache(sql, params);
	}

	@Override
	public <T> List<T> query(FS<T> fluentSql) {

		Tuple kv = getDialect().getSqlBuilder().buildSelectSQL(fluentSql);
		String sql = kv.getObject(0);
		Object[] params = kv.getObject(1);
		Class<T> modelClass = kv.getObject(2);

		StatementHandler sh = getStatementHandler();
		if (sh != null) {
			sql = sh.handle(sql);
		}

		return HbatisServiceManager.getHbatisService().use(commonRepository.getDatabase()).query(sql,
				ModelBuilder.buildQueryMapper(modelClass), params);
	}

	@Override
	public <T, R> List<R> queryObject(FS<T> fluentSql) {

		Tuple kv = getDialect().getSqlBuilder().buildSelectSQL(fluentSql);
		String sql = kv.getObject(0);
		Object[] params = kv.getObject(1);
		Class<R> modelClass = kv.getObject(2);

		StatementHandler sh = getStatementHandler();
		if (sh != null) {
			sql = sh.handle(sql);
		}

		return HbatisServiceManager.getHbatisService().use(commonRepository.getDatabase()).queryObject(sql, modelClass,
				params);
	}

	@Override
	public <T, R> R queryFirstObject(FS<T> fluentSql) {
		List<R> dataList = queryObject(fluentSql);
		if (dataList != null && !dataList.isEmpty()) {
			return dataList.get(0);
		}
		return null;
	}

	@Override
	public <T> T queryFirst(FS<T> fluentSql) {
		List<T> dataList = query(fluentSql);
		if (dataList != null && !dataList.isEmpty()) {
			return dataList.get(0);
		}
		return null;
	}

	@Override
	public int update(FS<?> fluentSql) {

		Pair kv = getDialect().getSqlBuilder().buildUpdateSQL(fluentSql);
		String sql = kv.getKey();
		Object[] params = kv.getValue();

		StatementHandler sh = getStatementHandler();
		if (sh != null) {
			sql = sh.handle(sql);
		}

		return HbatisServiceManager.getHbatisService().use(commonRepository.getDatabase()).update(sql, params);
	}

	@Override
	public int delete(FS<?> fluentSql) {

		Pair kv = getDialect().getSqlBuilder().buildDeleteSQL(fluentSql);
		String sql = kv.getKey();
		Object[] params = kv.getValue();

		StatementHandler sh = getStatementHandler();
		if (sh != null) {
			sql = sh.handle(sql);
		}

		return HbatisServiceManager.getHbatisService().use(commonRepository.getDatabase()).update(sql, params);

	}

	@Override
	public Serializable insert(FS<?> fluentSql) {

		Pair kv = getDialect().getSqlBuilder().buildInsertSQL(fluentSql);
		String sql = kv.getKey();
		Object[] params = kv.getValue();

		StatementHandler sh = getStatementHandler();
		if (sh != null) {
			sql = sh.handle(sql);
		}

		return commonRepository.insert(sql, params);
	}

	@Override
	public int count(FS<?> fluentSql) {

		Pair kv = getDialect().getSqlBuilder().buildCountSQL(fluentSql);
		String sql = kv.getKey();
		Object[] params = kv.getValue();

		StatementHandler sh = getStatementHandler();
		if (sh != null) {
			sql = sh.handle(sql);
		}

		return commonRepository.queryFirstObject(sql, Integer.class, params);
	}

	@Override
	public <T> Page<T> queryPage(FS<T> fluentSql, int pageNumber, int pageSize) {

		Tuple t = getDialect().getSqlBuilder().buildSelectSQL(fluentSql);
		String sql = t.getObject(0);
		Object[] params = t.getObject(1);
		Class<T> modelClass = t.getObject(2);

		StatementHandler sh = getStatementHandler();
		if (sh != null) {
			sql = sh.handle(sql);
		}

		return queryPage(sql, pageNumber, pageSize, modelClass, params);
	}

	@Override
	public <T> List<T> queryWithCache(FS<T> fluentSql) {

		Tuple t = getDialect().getSqlBuilder().buildSelectSQL(fluentSql);
		String sql = t.getObject(0);
		Object[] params = t.getObject(1);
		Class<T> modelClass = t.getObject(2);
		StatementHandler sh = getStatementHandler();
		if (sh != null) {
			sql = sh.handle(sql);
		}

		return querySqlListWithCache(sql, modelClass, params);
	}

	@Override
	public <T> T queryFirstWithCache(FS<T> fluentSql) {

		Tuple t = getDialect().getSqlBuilder().buildSelectSQL(fluentSql);
		String sql = t.getObject(0);
		Object[] params = t.getObject(1);
		Class<T> modelClass = t.getObject(2);
		StatementHandler sh = getStatementHandler();
		if (sh != null) {
			sql = sh.handle(sql);
		}

		return querySqlFirstWithCache(sql, modelClass, params);
	}

	@Override
	public <T> List<T> queryObject(String sql, Class<T> clazz, Object... params) {
		return commonRepository.queryObject(sql, clazz, params);
	}

	@Override
	public <T> List<T> queryObjectWithCache(String sql, Class<T> clazz, Object... params) {
		return HbatisServiceManager.getHbatisService().use(commonRepository.getDatabase()).withCache().queryObject(sql,
				clazz, params);
	}

	@Override
	public <T> T queryFirstObject(String sql, Class<T> clazz, Object... params) {
		return commonRepository.queryFirstObject(sql, clazz, params);
	}

	@Override
	public <T> T queryFirstObjectWithCache(String sql, Class<T> clazz, Object... params) {
		return HbatisServiceManager.getHbatisService().use(commonRepository.getDatabase()).withCache()
				.queryFirstObject(sql, clazz, params);
	}

	@Override
	public int[] batch(List<String> sql) {
		return commonRepository.batch(sql);
	}

	@Override
	public int[] batch(String sql, Object[][] params) {
		return commonRepository.batch(sql, params);
	}

	@Override
	public int[] batch(String sql, Object[][] params, int batchSize) {
		return commonRepository.batch(sql, params, batchSize);
	}

	@Override
	public int[] batch(List<String> sqlList, int batchSize) {
		return commonRepository.batch(sqlList, batchSize);
	}

}
